home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * *
- MicroGenesis BULK Disk Copier
- Copyright 1993 by MicroGenesis Software
-
- Original version in May of '93
-
- (email, in order of pref.)
- CIS:76476,1701
- AOL:JeffH66
- DELPHI:HEATONJ
- BIX: JHEATON
-
- MicroGenesis Software
- P.O. Box 25534
- St. Louis, MO 63125
- (314) 638-2506
- (314) 638-1731 FAX
-
- This source code may be distributed and modified freely. All I ask is that
- this message(inside the two **** lines remain). It is okay to add
- additional lines after here crediting whoever may modify this code. This
- code may be used in any work: public,private,comercial or shareware. If
- you do use it in some sort of product all I require is that you inform
- me that you will be using it(by fax, email, us-mail, however).
-
- Some of this source code is VERY dangerous! There are routines in here
- designed to format/write directly to the disk surface. The exact same
- routines are used to write to your hard disk drive. This code as is will
- not write to your hard disk drive, but be CAREFUL when you modify
- certian numbers or you may find yourself turning your hard drive into a
- 1.44meg floppy look-a-like!(I am not sure what would happen actually, by
- some amazing quirk, I never inverted the numbers and killed my hard drive,
- and loosing 200meg of info is not much of a fun "experiment".
-
- SO as a result if you use this source code, and reformat your hard drive
- or destroy it in some fassion I am not responsable. I provide no warranty
- for this product of any sort. Use it at your own risk. Use it only on
- A: and B: like it was designed for!
-
- A really easy modification of this source code would allow you to create a
- sort of a DISKCOPY for hard drives(even of different sizes). This source
- code is not designed to do this, but it would make for an interesting mod.
- If you need any advice on this EMAIL me.
-
- Why did I write this program? Two reasons. The first version just to see
- if I could still access drives direcly like the good old 8-bit computer
- days. Second. This will form the backbone of a background disk duplication
- program I am working on. I released the code because I couldnt find public
- info on alot of this stuff.
-
- Jeff Heaton, MicroGenesis Software
-
- By the way, the order form is for our other products. You dont need to
- pay for this one:)
-
- * *
- ****************************************************************************/
-
- #include <alloc.h>
- #include <bios.h>
- #include <ctype.h>
- #include <dir.h>
- #include <dos.h>
- #include <io.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <conio.h>
-
- #define FALSE 0
- #define TRUE (!FALSE)
-
- #define SECTORSIZE 512
-
- // BIOS Int13 services we make use of
- #define RESET 0
- #define LAST 1
- #define READ 2
- #define WRITE 3
- #define VERIFY 4
- #define FORMAT 5
-
- int density;// How many sectors are in a track
-
-
- void msg(char (*s))
- {
- printf("%s\n", s);
- _exit(1);
- }
-
- // Identify the error code with a real error message.
- void Error(int (status))
- {
- switch (status)
- {
- // case 0x00:msg("Operation Successful"); break;
- case 0x01:msg("Bad command"); break;
- case 0x02:msg("Address mark not found"); break;
- case 0x03:msg("Attempt to write on write-protected disk"); break;
- case 0x04:msg("Sector not found"); break;
- case 0x05:msg("Reset failed (hard disk)"); break;
- // case 0x06:msg("Disk changed since last operation"); break;
- case 0x07:msg("Drive parameter activity failed"); break;
- case 0x08:msg("DMA overrun"); break;
- case 0x09:msg("Attempt to DMA across 64K boundary"); break;
- case 0x0A:msg("Bad sector detected"); break;
- case 0x0B:msg("Bad track detected"); break;
- case 0x0C:msg("Unsupported track"); break;
- case 0x10:msg("Bad CRC/ECC on disk read"); break;
- case 0x11:msg("CRC/ECC corrected data error"); break;
- case 0x20:msg("Controller has failed"); break;
- case 0x40:msg("Seek operation failed"); break;
- case 0x80:msg("Attachment failed to respond"); break;
- case 0xAA:msg("Drive not ready (hard disk only"); break;
- case 0xBB:msg("Undefined error occurred (hard disk only)"); break;
- case 0xCC:msg("Write fault occurred"); break;
- case 0xE0:msg("Status error"); break;
- case 0xFF:msg("Sense operation failed"); break;
- default:return;
- }
- _exit(1);
- }
-
- // Identify what kind of diskette is installed in the specified drive.
- // Return the number of sectors per track assumed as follows:
- // 9 - 360 K and 720 K 5.25".
- //15 - 1.2 M HD 5.25".
- //18 - 1.44 M 3.5".
- int nsects(int drive)
- {
- static int nsect[] = {18, 15, 9};
- char *buffer;
- int i, status;
-
- // Read sector 1, head 0, track 0 to get the BIOS running.
- buffer = (char *)malloc(SECTORSIZE);
- biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
- status = biosdisk(READ, drive, 0, 10, 1, 1, buffer);
- if (status == 0x06) // Door signal change?
- status = biosdisk(READ, drive, 0, 0, 1, 1, buffer);
- for (i=0; i < sizeof(nsect)/sizeof(int); ++i)
- {
- biosdisk(RESET, drive, 0, 0, 0, 0, buffer);
- status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
- if (status == 0x06)
- status = biosdisk(READ, drive, 0, 0, nsect[i], 1, buffer);
- if (status == 0x00) break;
- }
- if (i == sizeof(nsect)/sizeof(int))
- {
- msg("Can't figure out how many sectors/track for this diskette.");
- }
- free(buffer);
- return(nsect[i]);
- }
-
-
- // Used to format a disk(a track at a time)
- // This only formats the track to the point that we can write to it.
- // If you would run format_track on each track of a disk the disk would
- // NOT be usable. It would, however, be ready to be copied to.
- //
- // Using this on your hard drive(drive 2 or higher) would not really be
- // a good idea! Infact the routine refuses to do so.
- void format_track(int drive,int track)
- {
- struct FORMAT_ARRAY
- {
- char track,head,sector,bytes;
- } array[30];
- union REGS r;
- struct SREGS s;
- int i;
- int head;
-
- if( (drive>1) )// DONT EVEN THINK OF FORMATING THE HD!
- return;
-
- for(head=0;head<=1;head++)
- {
- for(i=0;i<density;i++)
- {
- array[i].track=track;
- array[i].head=head;
- array[i].sector=i+1;
- array[i].bytes=2;
- }
-
- Error(biosdisk(FORMAT,drive,head,track,1,density,array));
- }
- }
-
- void main(void)
- {
- char str[80];
- char *buffer, *pbuf;
- int drive, head, track, status, buflength, ns;
- FILE *fp;
- union REGS r;
- long free;
- int tracks;
-
- puts("MicroGenesis BULK Disk Copier, Copyright 1993 by MicroGenesis Software\n");
-
- if( (fp=fopen("fc.$$$","wb"))==NULL)
- {
- perror("FC.$$$");
- exit(1);
- }
-
- printf("Enter source drive(A or B): ");
- gets(str);
-
- if(!*str)
- exit(0);
-
- drive = *str;
- drive = (islower(drive) ? toupper(drive) : drive) - 'A';
-
- printf("Please the source disk into ");
- printf("drive %c: and press -ENTER- :", drive + 'A');
- getch();
-
- if(drive>1)
- {
- printf("Cant use this on hard drives!\r");
- return;
- }
-
-
- // Determine number of sectors per track and allocate buffers.
-
- density = nsects(drive);
- buflength = density * SECTORSIZE;
- buffer = (char *)malloc(buflength);
-
- r.h.ah=0x1c;
- r.h.dl=1;
- int86(0x21,&r,&r);
-
- tracks=(r.h.al*r.x.dx);
- tracks=tracks/density;
- tracks=tracks/2;
-
- // Start writing data to diskette until there is no more data to write.
-
- printf("\n\n\nPreparing to copy disk:\n");
- printf("%i tracks, %i sectors per track\n",tracks,density);
-
-
- head = track = 0;
-
- for(track=0;track<=tracks;track++)
- {
- for(head=0;head<=1;head++)
- {
- Error(biosdisk(READ, drive, head, track,1, density, pbuf));
- fwrite(pbuf,512,density,fp);
- printf("Track: %i, Head: %i\r",track,head);
- }
- }
-
- for(;;)
- {
- printf("\n\nPlease the destination disk into ");
- printf("drive %c: and press -ENTER- :", drive + 'A');
- getch();
- putch('\n');
-
- fclose(fp);
- fp=fopen("FC.$$$","rb");
- for(track=0;track<=tracks;track++)
- {
- format_track(drive,track);
- for(head=0;head<=1;head++)
- {
- fread(pbuf,512,density,fp);
- Error(biosdisk(WRITE, drive, head, track,1, density, pbuf));
- printf("Track: %i, Sector: %i, Head: %i\r",track,0,head);
- }
- }
-
- printf("\nDone.\n");
- biosdisk(2, drive, 0, 0, 1, 1, buffer); /* Retract head */
- fclose(fp);
-
- printf("Make another copy of this disk(Y/N)");
- if(toupper(getch())=='N')
- break;
-
- }
- unlink("FC.$$$");
- } /* end main */
-